package com.woniuxy.yoga.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.admin.dao.mapper.AdminLoginLogMapper;
import com.woniuxy.yoga.admin.dao.mapper.AdminRoleMapper;
import com.woniuxy.yoga.admin.dao.model.AdminAccount;
import com.woniuxy.yoga.admin.dao.mapper.AdminAccountMapper;
import com.woniuxy.yoga.admin.dao.model.AdminLoginLog;
import com.woniuxy.yoga.admin.dao.model.AdminRole;
import com.woniuxy.yoga.admin.model.dto.AdminAccountLoginDTO;
import com.woniuxy.yoga.admin.model.dto.adminaccount.AdminAccountAddDTO;
import com.woniuxy.yoga.admin.model.dto.adminaccount.AdminAccountSelectDTO;
import com.woniuxy.yoga.admin.model.dto.adminaccount.AdminByAccountIdDTO;
import com.woniuxy.yoga.admin.model.exception.AdminException;
import com.woniuxy.yoga.admin.model.exception.AdminExceptionCode;
import com.woniuxy.yoga.admin.model.form.AdminAccountLoginForm;
import com.woniuxy.yoga.admin.model.param.AdminAccountLoginParam;
import com.woniuxy.yoga.admin.model.param.adminaccount.*;
import com.woniuxy.yoga.admin.service.AdminAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.statedata.AdminState;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理员账号表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class AdminAccountServiceImpl extends ServiceImpl<AdminAccountMapper, AdminAccount> implements AdminAccountService {


    @Autowired
    private AdminAccountMapper adminAccountMapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 管理员端账号密码登录
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AdminAccountLoginDTO loginAdmin(AdminAccountLoginParam param) throws UnknownHostException {
        QueryWrapper<AdminAccount> queryWrapper = new QueryWrapper<>();
        //判断管理员账号是否存在
        queryWrapper.eq("account_name",param.getAccountName());
        AdminAccount adminAccount = adminAccountMapper.selectOne(queryWrapper);
        if (adminAccount==null) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTNAME_NOT_EXITS);
        }
        if (adminAccount.getAccountState()!= AdminState.ADMIN_ACCOUNT_NORMAL) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        }
        //判断管理员密码是否正确
        if (!param.getAccountPassword().equals(adminAccount.getAccountPassword())) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTPASS_ERROR);
        }
        AdminRole adminRole = adminRoleMapper.selectById(adminAccount.getRoleId());
        //生成管理员登录日志
        AdminLoginLog adminLoginLog = BeanUtil.toBean(adminAccount, AdminLoginLog.class);
        String[] split = InetAddress.getLocalHost().toString().split("/");
        adminLoginLog.setLoginAddress(split[1]);
        String loginTime = DateUtil.format(new Date(System.currentTimeMillis()), "yyyy-MM-dd HH:mm:ss");
        adminLoginLog.setLoginTime(loginTime);
        adminLoginLog.setLogRemarks(adminRole.getRoleName()+adminAccount.getAccountName()+"在"+loginTime+"登录");
        rabbitTemplate.convertAndSend("create-adminLoginLog",adminLoginLog);
        //返回账号信息给前端
        AdminAccountLoginDTO dto = BeanUtil.toBean(adminAccount, AdminAccountLoginDTO.class);
        return dto;
    }

    /**
     * 平台添加管理员
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AdminAccountAddDTO addAdmin(AdminAccountAddParam param) {
        AdminAccount account = adminAccountMapper.selectById(param.getAddAccountId());
        if (account==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        if (account.getAccountState()!=AdminState.ADMIN_ACCOUNT_NORMAL)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        //用户名不能重复
        List<AdminAccount> adminAccounts = adminAccountMapper.selectList(new QueryWrapper<AdminAccount>());
        List<String> adminNames = adminAccounts.stream().map(o -> o.getAccountName()).collect(Collectors.toList());
        if (adminNames.contains(param.getAccountName()))throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTNAME_REPEAT);
        //手机号码不能重复
        List<String> adminPhones = adminAccounts.stream().map(o -> o.getAccountPhone()).collect(Collectors.toList());
        if (adminPhones.contains(param.getAccountPhone()))throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTPHONE_REPEAT);
        //管理员账号表新增
        AdminAccount adminAccount = BeanUtil.toBean(param,AdminAccount.class);
        adminAccount.setAddTime(DateUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        adminAccount.setAddUser(account.getAccountName());
        adminAccount.setAccountState(AdminState.ADMIN_ACCOUNT_NORMAL);
        adminAccount.setRoleId(2);
        adminAccountMapper.insert(adminAccount);
        return BeanUtil.toBean(adminAccount,AdminAccountAddDTO.class);
    }

    /**
     * 平台删除管理员
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAdmin(AdminAccountDeleteParam param) {
        //查询账号是否存在
        AdminAccount adminAccount = adminAccountMapper.selectById(param.getAccountId());
        if (adminAccount==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //高级管理员不能被删除
        if (adminAccount.getRoleId()== AdminState.HIGHTER_ADMIN) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_HIGHERADMIN_PROTECT);
        }
        //账号状态是否已删除
        if (adminAccount.getAccountState()==AdminState.ADMIN_ACCOUNT_DELETE)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        adminAccount.setAccountState(AdminState.ADMIN_ACCOUNT_DELETE);
        adminAccountMapper.updateById(adminAccount);
    }

    /**
     * 分页查询管理员
     * @param param
     * @return
     */
    @Override
    public PageInfo selectAdmin(AdminAccountPageParam param) {
        //创建分页查询对象
        Page<AdminAccount> page = new Page<AdminAccount>(param.getCurrent()==null?1:param.getCurrent(),
                param.getSize()==null?10:param.getSize());
        LambdaQueryWrapper<AdminAccount> wrapper = new LambdaQueryWrapper<>();
        //根据账号状态条件查询
        if (param.getAccountState()!=null){
            wrapper.eq(AdminAccount::getAccountState,param.getAccountState());
        }else {
            wrapper.ne(AdminAccount::getAccountState,AdminState.ADMIN_ACCOUNT_DELETE);
        }
        //根据添加人条件查询
        if (param.getAddUser()!=null&&!param.getAddUser().equals("")){
            wrapper.eq(AdminAccount::getAddUser,param.getAddUser());
        }
        Page<AdminAccount> accountPage = adminAccountMapper.selectPage(page, wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(BeanUtil.copyToList(accountPage.getRecords(), AdminAccountSelectDTO.class));
        return pageInfo;
    }

    /**
     *管理员修改密码
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdminPass(AdminPassUpdateParam param) {
        //查询账号是否存在
        AdminAccount adminAccount = adminAccountMapper.selectById(param.getAccountId());
        if (adminAccount==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //查询账号状态是否正常
        if (adminAccount.getAccountState()!=AdminState.ADMIN_ACCOUNT_NORMAL)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        //对比原密码是否相同
        if (adminAccount.getAccountPassword().equals(param.getAccountNewPass()))throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTPASS_UPREPEAT);
        //修改密码
        adminAccount.setAccountPassword(param.getAccountNewPass());
        adminAccountMapper.updateById(adminAccount);
    }

    /**
     *禁用管理员账号
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableAdminAccount(AdminAccountDisableParam param) {
        //管理员账号是否存在
        AdminAccount adminAccount = adminAccountMapper.selectById(param.getAccountId());
        if (adminAccount==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //高级管理员不能被禁用
        if (adminAccount.getRoleId()== AdminState.HIGHTER_ADMIN) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_HIGHERADMIN_PROTECT);
        }
        //账号状态是否正常
        if (adminAccount.getAccountState()!=AdminState.ADMIN_ACCOUNT_NORMAL)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        //修改账号状态
        adminAccount.setAccountState(AdminState.ADMIN_ACCOUNT_DISABLE);
        adminAccountMapper.updateById(adminAccount);
    }

    /**
     *启用管理员账号
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updAdminAccount(AdminAccountUpdParam param) {
        //管理员账号是否存在
        AdminAccount adminAccount = adminAccountMapper.selectById(param.getAccountId());
        if (adminAccount==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //高级管理员不能被操作
        if (adminAccount.getRoleId()== AdminState.HIGHTER_ADMIN) {
            throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_HIGHERADMIN_PROTECT);
        }
        //管理员账号是否是禁用状态
        if (adminAccount.getAccountState()!=AdminState.ADMIN_ACCOUNT_DISABLE)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        adminAccount.setAccountState(AdminState.ADMIN_ACCOUNT_NORMAL);
        adminAccountMapper.updateById(adminAccount);
    }

    /**
     * 通过账号ID查询账号信息
     * @param accountId
     * @return
     */
    @Override
    public AdminByAccountIdDTO selAdminByAccountId(Integer accountId) {
        //查询商家账号信息存在
        AdminAccount account = adminAccountMapper.selectById(accountId);
        if (account==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //账号状态是否正常
        if (account.getAccountState()!=AdminState.ADMIN_ACCOUNT_NORMAL)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        //装换类型
        AdminByAccountIdDTO dto = BeanUtil.toBean(account, AdminByAccountIdDTO.class);
        return dto;
    }

    /**
     * 验证密码
     * @param param 参数
     */
    @Override
    public void checkOldPwd(CheckAdminPassParam param) {
        AdminAccount account = adminAccountMapper.selectById(param.getAccountId());
        if (account==null)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        //账号状态是否正常
        if (account.getAccountState()!=AdminState.ADMIN_ACCOUNT_NORMAL)throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTSTATE_ERROR);
        if (!account.getAccountPassword().equals(param.getPassword())) throw new AdminException(AdminExceptionCode.ADMIN_EXCEPTION_CODE_ACCOUNTPASS_ERROR);
    }
}
